package com.gw.booking.service;

import com.gw.booking.common.ApiException;
import com.gw.booking.common.Constant;
import com.gw.booking.common.MessageCode;
import com.gw.booking.common.Util;
import com.gw.booking.dto.PageDto;
import com.gw.booking.dto.backend.DiscountListDtoOut;
import com.gw.booking.dto.wechat.WCustomerDiscountDtoOut;
import com.gw.booking.dto.wechat.WDiscountListDtoOut;
import com.gw.booking.entity.Customer;
import com.gw.booking.entity.CustomerDiscount;
import com.gw.booking.entity.Discount;
import com.gw.booking.entity.LoginToken;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

@Service
public class CustomerDiscountService {
    @Autowired
    SessionFactory sessionFactory;

    public PageDto<WCustomerDiscountDtoOut> list(LoginToken loginToken, Integer state, int page, int size) {
        Session session = sessionFactory.getCurrentSession();
        if (Constant.FALSE.equals(state)) {
            // 收藏的优惠
            String sql = " select cd.id as customerDiscountId, m.id as merchantId, m.shop_name as shopName, d.id as discountId, " +
                    " d.state as discountState ,d.limited as limited , d.limited_at as limitedAt, d.reserve as reserve, " +
                    " d.prompt as prompt, d.condition_c as conditionC, d.condition_j as conditionJ, d.content_c as contentC,d.content_j as contentJ " +
                    " from customer_discount cd inner join discount d on d.id = cd.discount_id " +
                    " inner join merchant m on d.merchant_id = m.id ";
            String sqlWhere = " where cd.customer_id = :customerId ";
            List<WCustomerDiscountDtoOut> items = session.createSQLQuery(sql + sqlWhere)
                    .setParameter("customerId", loginToken.getUserId())
                    .setResultTransformer(Transformers.aliasToBean(WCustomerDiscountDtoOut.class))
                    .list();
            List<WDiscountListDtoOut> wDiscountListDtoOutList = getMerchantDiscountList(items);
            List<WDiscountListDtoOut> result = new ArrayList<>();
            for (int i = ((page - 1) * size); i < page * size; i++) {
                if (i > wDiscountListDtoOutList.size() - 1) {
                    break;
                }
                result.add(wDiscountListDtoOutList.get(i));
            }
            return new PageDto(page, size, wDiscountListDtoOutList.size(), result);
        } else {
            //使用的优惠
            String sql = " select m.id as merchantId, m.shop_name as shopName, d.id as discountId, " +
                    " d.state as discountState ,d.limited as limited , d.limited_at as limitedAt, d.reserve as reserve, " +
                    " d.prompt as prompt, d.condition_c as conditionC, d.condition_j as conditionJ, d.content_c as contentC, d.content_j as contentJ " +
                    " from orders o inner join discount d on d.id = o.discount_id " +
                    " inner join merchant m on d.merchant_id = m.id ";
            String sqlWhere = " where o.customer_id = :customerId and o.state = :orderState ";
            String sqlGroup = " group by m.id, m.shop_name, d.id, d.state,d.limited, d.limited_at, d.reserve, " +
                    " d.prompt, d.condition_c, d.condition_j,d.content_c , d.content_j ";
            List<WCustomerDiscountDtoOut> items = session.createSQLQuery(sql + sqlWhere + sqlGroup)
                    .setParameter("customerId", loginToken.getUserId())
                    .setParameter("orderState", Constant.ORDER_STATUS_SUCCESS)
                    .setResultTransformer(Transformers.aliasToBean(WCustomerDiscountDtoOut.class))
                    .list();
            List<WDiscountListDtoOut> wDiscountListDtoOutList = getMerchantDiscountList(items);
            List<WDiscountListDtoOut> result = new ArrayList<>();
            for (int i = (page - 1) * size; i < page * size; i++) {
                if (i > wDiscountListDtoOutList.size() - 1) {
                    break;
                }
                result.add(wDiscountListDtoOutList.get(i));
            }
            return new PageDto(page, size, wDiscountListDtoOutList.size(), result);
        }
    }

    public void txAdd(LoginToken loginToken, Integer discountId) {
        Session session = sessionFactory.getCurrentSession();
        Discount discount = (Discount) session.get(Discount.class, discountId);
        Customer customer = (Customer) session.get(Customer.class, loginToken.getUserId());
        if (discount == null || customer == null) {
            throw new ApiException(MessageCode.CODE_PARAMETER_ERROR);
        }
        CustomerDiscount customerDiscount = new CustomerDiscount();
        customerDiscount.setCreatedAt(new Timestamp(System.currentTimeMillis()));
        customerDiscount.setCustomerId(customer.getId());
        customerDiscount.setDiscountId(discountId);
        session.save(customerDiscount);
        session.flush();
    }

    public void txDelete(LoginToken loginToken, Integer customerDiscountId) {
        Session session = sessionFactory.getCurrentSession();
        CustomerDiscount customerDiscount = (CustomerDiscount) session.get(CustomerDiscount.class, customerDiscountId);
        if (customerDiscount == null) {
            throw new ApiException(MessageCode.CODE_DISCOUNT_NOT_EXISTS);
        }
        if (customerDiscount.getCustomerId() != loginToken.getUserId()) {
            throw new ApiException(MessageCode.CODE_NO_PRIVILEGE);
        }
        session.delete(customerDiscount);
        session.flush();
    }

    public List<WDiscountListDtoOut> getMerchantDiscountList(List<WCustomerDiscountDtoOut> items) {
        List<WDiscountListDtoOut> wDiscountListDtoOutList = new ArrayList<>();
        for (WCustomerDiscountDtoOut wCustomerDiscountDtoOut : items) {
            int i = 0;
            for (WDiscountListDtoOut wDiscountListDtoOut : wDiscountListDtoOutList) {
                if (wDiscountListDtoOut.getMerchantId().equals(wCustomerDiscountDtoOut.getMerchantId())) {
                    wDiscountListDtoOut.getwCustomerDiscountDtoOutList().add(wCustomerDiscountDtoOut);
                    i++;
                    break;
                }
            }
            if (i == 0) {
                WDiscountListDtoOut wDiscountListDtoOut = new WDiscountListDtoOut();
                wDiscountListDtoOut.setMerchantId(wCustomerDiscountDtoOut.getMerchantId());
                wDiscountListDtoOut.setShopName(wCustomerDiscountDtoOut.getShopName());
                List<WCustomerDiscountDtoOut> wCustomerDiscountDtoOutList = new ArrayList<>();
                wCustomerDiscountDtoOutList.add(wCustomerDiscountDtoOut);
                wDiscountListDtoOut.setwCustomerDiscountDtoOutList(wCustomerDiscountDtoOutList);
                wDiscountListDtoOutList.add(wDiscountListDtoOut);
            }
        }
        return wDiscountListDtoOutList;
    }
}
